/**
 * 
 */
package com.jolestar.yayaweibotong.dao;

import java.io.Serializable;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.jolestar.yayaweibotong.ServiceType;
import com.jolestar.yayaweibotong.YayaException;

/**
 * @author yuanming@staff.sina.com.cn
 * 
 */
public abstract class AbstractDomain implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 8726732685683409489L;
	protected Entity entity;
	protected Key key;
	protected ServiceType serviceType;
	protected String originalId = null;

	public AbstractDomain(ServiceType serviceType, String originalId) {
		this.serviceType = serviceType;
		this.originalId = originalId;
		key = KeyFactory.createKey(this.getClass().getName(),
				DomainFactory.generateId(serviceType, originalId));
		this.entity = new Entity(key);
	}

	public AbstractDomain(Entity entity) {
		Key key = entity.getKey();
		String kind = key.getKind();
		if (!this.getClass().getName().equals(kind)) {
			throw new YayaException(
					"this domain object can not accept this kind entity");
		}
		this.key = key;
		this.entity = entity;
		String keyName = key.getName();
		int index = keyName.lastIndexOf('@');
		this.originalId = keyName.substring(0, index);
		this.serviceType = ServiceType.fromHost(keyName.substring(index+1));
	}

	public String getOriginalId() {
		return this.originalId;
	}

	public ServiceType getServiceType() {
		return this.serviceType;
	}

	public Key getKey() {
		return this.key;
	}
	
	public String getKeyName(){
		return this.key.getName();
	}

	/**
	 * 
	 * @param <X>
	 * @param property
	 * @return
	 */
	@SuppressWarnings("unchecked")
	protected <X> X get(String property) {
		return (X) entity.getProperty(property);
	}

	/**
	 * Returns a property value.
	 * 
	 * @param property
	 *            the property name
	 * @param valueWhenNull
	 * @return the value
	 */
	@SuppressWarnings("unchecked")
	protected <X> X get(String property, X valueWhenNull) {
		X value = (X) get(property);
		return (value == null) ? valueWhenNull : value;
	}

	protected void set(String property, Object value) {
		this.entity.setProperty(property, value);
	}

	// public void load() {
	// try {
	// this.entity.setPropertiesFrom(datastore.get(this.key));
	// } catch (EntityNotFoundException e) {
	// throw new YayaException(e);
	// }
	// }

	public void save() {
		DomainFactory.getDatastore().put(this.entity);
	}

	public void delete() {
		DomainFactory.getDatastore().delete(this.entity.getKey());
	}

}
